import paramiko, time, socket, re
COLOR_CODE_MAPPING = {"1":"BOLD", "31": "RED", "32": "GREEN", "33":"YELLOW", "34":"BLUE", "35":"MAGENTA", "36":"CYAN"}
KEY_CODE_MAPPING = { 13: "\x0d", 38:"\x1b\x4f\x41", 40:"\x1b\x4f\x42", 39:"\x1b\x4f\x43", 37:"\x1b\x4f\x44", 9:"\x09"}
CMD_LIST = {'\x1b[H\x1b[J':"CLEAR"}

class KeycodeConver(object):
    """
        convert to vt100 code
    """
    def __init__(self, result):
        self._result = result

    def parser(self):
        if not self._result:
            return ""
        res = KEY_CODE_MAPPING.get(self._result, None)
        if res:
            return res
        else:
            if type(self._result) is int:
                return chr(self._result)

        return self._result



class CommandParser():
    def __init__(self, result):
        self._result = result
    
    def parser(self):
        if not self._result:
            return ""
        return CMD_LIST.get(self._result, None)

class TextParser(object):
    """
        parser to html from vt100 code
    """
    def __init__(self, result):
        self._result = result

    def add_font_color(self, color, text):
        print "color = "+color+" text = "+str(len(text)) + str("'"+text+"'")
        html_text = text
        if not color or color == "00" or ";" not in color:
            return html_text
        color_type, color_code = color.split(";")
        if color_type == "01":
            html_text = "<b>"+text+"</b>"
        if color_code in COLOR_CODE_MAPPING:
            html_text = "<span style='color:%s'>%s</span>" % (COLOR_CODE_MAPPING[color_code], text)

        return html_text

    def parser(self):
        print repr(self._result)
        if '\x1b' not in self._result:
            return self._result
        all_items = [v for v in self._result.split(b'\x1b') if v ]
        html_result = []
        for item in all_items:
            if item.startswith("[") and item.count("m") > 0:
                color, text = item.split("m", 1)
                html = self.add_font_color(color[1:], text) 
                html_result.append(html)
            else:
                html_result.append(item)
        return self._result if not html_result else "".join(html_result)

class HtmlParser(object):
    def parser(self, result, show, exe):
        parser_result = CommandParser(result).parser()
        if parser_result:
            return {"func":exe, "result":parser_result}

        parser_result = TextParser(result).parser()
        if parser_result:
            return {"func":show, "result":parser_result}

        return {"func":show, "result":result}

    def convert(self, cmd):
        cmd = KeycodeConver(cmd).parser()
        return cmd

class remoteSSHClient(object):
    def __init__(self, host,  user, passwd, port = 22, width=200, height=24):
        self._host = host
        self._port = port
        self._user = user
        self._passwd = passwd
        self._width = width
        self._height = height
        self._init_channel()
        self._parser = HtmlParser()


    def convert(self, result):
        return self._parser.convert(result)

    def parser(self, result, show, exe):
        return self._parser.parser(result, show, exe)

    def _init_channel(self):

        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(str(self._host),int(self._port), self._user, self._passwd, timeout=120)
        chan = ssh.get_transport().open_session()
        #chan.get_pty()
        chan.get_pty(width=int(self._width), height=int(self._height))
        chan.invoke_shell()
        self._ssh = ssh
        self.channel = chan

    def collect_cmd_result(self):
        for cmd in CMD_LIST:
            self.channel(cmd)
            self.cmd_result()
        

    def close(self):
        self._ssh.close()


if __name__ == "__main__":

    import threading, socket
    host = socket.gethostbyname(socket.gethostname())
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    #ssh.connect(str("172.16.206.50"),int(22), 'root', '111111')
    ssh.connect(str("localhost"),int(22), 'kangta123', 'hyxkangta123@')
    chan = ssh.get_transport().open_session()
    #chan.setblocking(0)
    chan.get_pty()
    chan.invoke_shell()


    #_lock = threading.Lock()
    html = HtmlParser()
    def recv():
        num = 0
        while True:
            result = chan.recv(1024)
            if chan.exit_status_ready():
                break
            print str(num) + ":" + str(html.parser(result, "show", "exec"))
            num += 1

    t = threading.Thread(target=recv)
    t.daemon = True
    t.start()

    time.sleep(1)
    import struct
    cmds = ['pwd\x0d']
    #cmds = ["\x09", "\x09", "y"]

    
    def sender():
        index = 0
        while True:
            print "send :" + repr(cmds[index])
            print chan.send(cmds[index])
            time.sleep(1)
            #chan.shutdown(2)
            index += 1
            if index >= len(cmds):
                break

    t1 = threading.Thread(target=sender)
    t1.daemon = True
    t1.start()


    time.sleep(10)

